home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
listings
/
v_10_12
/
1012047a
< prev
next >
Wrap
Text File
|
1992-10-08
|
4KB
|
211 lines
page ,132
; masm tisr ; >err
.286p
.xlist
include ..\..\include\bogus.inc
.list
Words struc
LoWord dw ?
HiWord dw ?
Words ends
EOI equ 020h ; EOI command for PIC
INTA00 equ 020h ; Master PIC control
INTA01 equ 021h ; Master PIC mask register
INT_MASTER_0 equ 08h ; Master PIC INT number
INTB00 equ 0A0h ; Slave PIC control
INTB01 equ 0A1h ; Slave PIC mask register
INT_SLAVE_0 EQU 70h ; Slave PIC INT number
;
; Set variables for our interrupt number
;
ife (FAKE_IRQ GE 8)
INT_DEV equ (INT_MASTER_0+(FAKE_IRQ AND 7))
PIC00 equ INTA00
PIC01 equ INTA01
else
INT_DEV equ (INT_SLAVE_0+(FAKE_IRQ AND 7))
INT_MASK equ 1 SHL (FAKE_IRQ AND 7)
PIC00 equ INTB00
PIC01 equ INTB01
endif
page
CONST SEGMENT DWORD PUBLIC 'DATA'
sdNoBogus db 'I do not see the bogus device.',0dh,0ah,'$'
sdPrompt db 0Dh,0Ah,'S)tart, or Q)uit: ','$'
sdCRLF db 0Dh,0Ah,'$'
sdDot db '.','$'
CONST ENDS
DATA SEGMENT DWORD PUBLIC 'DATA'
dwCount1 dw 0
dwCount2 dw 0
lpPrevISR dd 0 ; address of prior ISR
fStopping db 0 ; TRUE when stopping
DATA ENDS
STACK SEGMENT DWORD STACK 'STACK'
db 512 dup (?)
STACK ENDS
DGroup GROUP CONST,DATA,STACK
page
;IP IntSvcRtn - The Interrupt Service Routine
;
; WARNINGS
;
; NOTES
; This ISR generally increments an interrupt count (dwCount1)
; and re-arms the device.
;
; If the "fStopping" flag is set, the device is not re-armed.
;
FIXED_TEXT SEGMENT PARA PUBLIC 'CODE'
segData1 dw DGroup
assume CS:FIXED_TEXT,DS:NOTHING
IntSvcRtn proc far
push ax
push dx
push ds
mov ds,segData1
assume ds:DGroup
inc dwCount1
mov al,NOT FAKE_CTL_EOI
mov dx,FAKE_PORT
out dx,al ; send EOI to device
mov al,EOI
out PIC00,al ; send EOI to PIC
ife (PIC00 EQ INTA00)
out INTA00,al ; send EOI to master PIC, too
endif
cmp fStopping,0 ; exiting?
jnz isr9 ; if so, then don't restart
mov al,NOT FAKE_CTL_START
mov dx,FAKE_PORT
out dx,al ; restart I/O
isr9:
pop ds
assume ds:NOTHING
pop dx
pop ax
iret
IntSvcRtn endp
FIXED_TEXT ENDS
page
;IP __main - program entry point
;
; NOTES
; The user is prompted to S)tart or Q)uit the program. If
; "S" is selected, the programs enables interrupts and arms
; the device, printing out a dot each time the device interrupts.
;
_TEXT SEGMENT PARA PUBLIC 'CODE'
segData2 dw DGroup
segFixed dw FIXED_TEXT
assume cs:_TEXT,ds:NOTHING
__main label far
mov ds,segData2 ; Initialize default data segment
assume ds:DGroup
mov dx,FAKE_PORT
in al,dx ; Is the bogus device present ?
or al,al
jns ml0 ; skip if so
mov dx,OFFSET DGroup:sdNoBogus
mov ah,9
int 21h ; else print error message
mov ax,4C01h
int 21h ; and exit
ml0:
mov ax,3500h+INT_DEV
cli
int 21h ; Query the current ISR
mov lpPrevISR.LoWord,bx
mov lpPrevISR.HiWord,es ; Save it
mov dx,OFFSET FIXED_TEXT:IntSvcRtn
push ds
mov ds,segFixed
assume ds:NOTHING
mov ax,2500h+INT_DEV
int 21h ; Set our ISR
pop ds
assume ds:DGroup
sti
mov dx,OFFSET DGroup:sdPrompt
mov ah,9
int 21h ; "S)tart or Q)uit
ml1:
mov dl,0FFh
mov ah,6
int 21h ; read from console, nowait
jz ml3
or al,40h
cmp al,'q'
je ml8 ; skip if "Q" pressed
cmp al,'s'
jne ml3 ; skip if "S" not pressed
cli
in al,PIC01 ; unmask the interrupt
and al,NOT INT_MASK
out PIC01,al
sti
mov al,NOT FAKE_CTL_START
mov dx,FAKE_PORT
out dx,al ; start device I/O
ml3:
mov ax,dwCount1
cmp ax,dwCount2
je ml4 ; skip if the count of interrupts unchanged
mov dwCount2,ax
mov dx,OFFSET DGroup:sdDot
mov ah,9
int 21h ; else, display a dot
ml4:
jmp ml1 ; loop for more
ml8:
mov fStopping,1 ; Tell the ISR to stop
mov dx,FAKE_PORT
ml9:
in al,dx
rcr al,1
jnc ml9 ; loop while busy
cli
in al,PIC01
or al,INT_MASK
out PIC01,al ; mask the interrupt level
sti
push ds
lds dx,lpPrevISR
assume ds:NOTHING
mov ax,2500h+INT_DEV
int 21h ; restore the previous ISR
pop ds
assume ds:DGroup
mov ax,4C00h
int 21h ; exit
_TEXT ENDS
end __main